/***************************************************************************************
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
*
* NEMU is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

#include "sdb.h"

// #define NR_WP 32

// typedef struct watchpoint {
//   int NO;
//   struct watchpoint *next;

//   /* TODO: Add more members if necessary */
//   char str[32];
//   uint32_t val;
// } WP;

static WP wp_pool[NR_WP] = {};
static WP *head = NULL, *free_ = NULL;

void init_wp_pool() {
  int i;
  for (i = 0; i < NR_WP; i ++) {
    wp_pool[i].NO = i;
    wp_pool[i].next = (i == NR_WP - 1 ? NULL : &wp_pool[i + 1]);
  }

  head = NULL;
  free_ = wp_pool;
}

/* TODO: Implement the functionality of watchpoint */

WP* new_wp(){
  // the free list is empty
  if(free_ == NULL){
    assert(0);
  }
  // get the first free node
  WP* node = free_;
  free_ = free_->next;
  return node;

}

void free_wp(WP* wp){
  // free is empty
  if(free_ == NULL){
    free_ = wp;
  }
  else{
    wp->next = free_;
    free_ = wp;
  }

  // delete the wp from head list
  if(head == NULL){
    assert(0);
  }
  if( wp->NO == head->NO){
    head = head->next;
  }
  else{
    WP* prev = head;
    WP* current = head->next;
    while(current != NULL){
      if(current->NO == wp->NO){
        prev->next = current->next;
      }
      prev = current;
      current = current->next;
    }
  }

}

WP* get_head(){
  return head;
}

void add_head(WP* node){
  node->next = head;
  head = node;
}